﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Windows.Forms.DataVisualization;

namespace EasyTrader
{
    // 봉테이블 목록
    using BarTableList = List<EasyTrader.DataSet.BarDataTable>;
    // 봉 정보 목록
    using BarDataList = List<EasyTrader.DataSet.BarDataItem>;
    // 봉정보 목록을 다시 목록으로 만든 것.
    using BarDataCollection = List<EasyTrader.DataSet.BarDataItemList>;
    // dde 일자별 정보를 모아 놓은 목록
    using OptMonthData = List<EasyTrader.Option.DDEDayData>;
    using DDEDataList = List<EasyTrader.Option.DDEData>;
    using SimpleDataList = List<EasyTrader.DataSet.SimpleData>;
    using DayCrossDataList = List<EasyTrader.DataSet.DayCrossData>;

    // 이 클래스는 데이터를 보존하는 클래스이다.
    // 데이터 테이블들을 가지고 있으며 서버에서 데이터를 받은 역할을 한다.
    public class ETDataSet : System.Data.DataSet
    {
        private DayCrossDataList m_OptCrossMonthData = new DayCrossDataList();
        public DayCrossDataList OptCrossMonthData
        {
            get { return m_OptCrossMonthData; }
            set { m_OptCrossMonthData = value; }
        }


        private bool m_DDEDataCreated = false;
        public bool DDEDataCreated
        {
            get { return m_DDEDataCreated; }
            set { m_DDEDataCreated = value; }
        }

        public void CreateDDEData()
        {
            if (m_DDEDataCreated == false)
            {
                CreateMonthData();
                FillDDEMonthData();
                FillCrossMonthData();
                m_DDEDataCreated = true;
            }
        }


        public bool GetFutOptOHLC(int a_StartIndex, int a_EndIndex, ref double a_Open, ref double a_High, ref double a_Low, ref double a_Close)
        {
            EasyTrader.DataSet.FutOptChartTable a_Table = GetFutOptChartTable();
            if (a_Table == null)
                return false;
            if (a_Table.Rows.Count == 0)
                return false;
            if (a_StartIndex < 0 || a_StartIndex > a_Table.Rows.Count - 1)
                return false;
            if (a_StartIndex > a_EndIndex || a_EndIndex < 0)
                return false;

            int endIndex = a_EndIndex;
            if (endIndex < 0)
                return false;
            if (endIndex > a_Table.Rows.Count - 1)
                endIndex = a_Table.Rows.Count - 1;


            DataRow row = a_Table.Rows[a_StartIndex];
            a_Open = Convert.ToDouble(row["시가"]);
            a_High = Convert.ToDouble(row["고가"]);
            a_Low = Convert.ToDouble(row["저가"]);
            for (int i = a_StartIndex; i <= endIndex; i++)
            {
                row = a_Table.Rows[i];
                double high = Convert.ToDouble(row["고가"]);
                double low = Convert.ToDouble(row["저가"]);
                a_Close = Convert.ToDouble(row["종가"]);
                if (high > a_High)
                    a_High = high;
                if (low < a_Low)
                    a_Low = low;
            }
            return true;
        }

        private void FillCrossMonthData()
        {
            OptMonthData opMonData = m_OptionMonthData;
            for (int j = 0; j < opMonData.Count; j++)
            {
                // 해당 날짜의 dde 목록을 가져 온다. 
                EasyTrader.Option.DDEDayData dayDataCol = opMonData[j];
                for (int i = 0; i < dayDataCol.CollectionList.Count; i++)
                {
                    EasyTrader.Option.DDEData dde = dayDataCol.CollectionList[i];
                    
                    double outVal = 0.0;
                    string centerVal = "";
                    // 콜 최신 마디가 찾기
                    bool result = false;
                    if (dde.CallCode != null && dde.CallCode.ToString() != "")
                    {
                        result = GetRecentCrossVal(Convert.ToInt32(dayDataCol.Date), 0, dde.CallCode.ToString(), out outVal, out centerVal);
                        if (result == true)
                        {
                            dde.CallJoint = outVal;
                            dde.CallJointCenter = centerVal;
                        }
                        // 콜 최신 목표가 찾기
                        result = GetRecentCrossVal(Convert.ToInt32(dayDataCol.Date), 1, dde.CallCode.ToString(), out outVal, out centerVal);
                        if (result == true)
                        {
                            dde.CallTarget = outVal;
                            dde.CallTargetCenter = centerVal;
                        }
                    }

                    if (dde.PutCode != null && dde.PutCode.ToString() != "")
                    {
                        result = GetRecentCrossVal(Convert.ToInt32(dayDataCol.Date), 0, dde.PutCode.ToString(), out outVal, out centerVal);
                        if (result == true)
                        {
                            dde.PutJoint = outVal;
                            dde.PutJointCenter = centerVal;
                        }

                        result = GetRecentCrossVal(Convert.ToInt32(dayDataCol.Date), 1, dde.PutCode.ToString(), out outVal, out centerVal);
                        if (result == true)
                        {
                            dde.PutTarget = outVal;
                            dde.PutTargetCenter = centerVal;
                        }
                    }
                }
            }
        }


        // 주어진 날짜보다 작은 마디가와 목표가를 가져온다. 
        // 마디가와 목표가는 당일 발생한 것을 인정하지 아니한다.
        private bool GetRecentCrossVal(int a_Date, int a_Type, string a_OpCode, out double a_OutVal, out string a_Center)
        {
            a_OutVal = 0.0;
            a_Center = "";
            // 가장 최근 날짜 부터 역순으로 검색을 한다.
            for (int i = m_OptCrossMonthData.Count - 1; i > -1; i--)
            {
                EasyTrader.DataSet.DayCrossData curData = m_OptCrossMonthData[i];

                // 현재 날짜가 주어진 날짜보다 크거나 같으면 그 이후에 발생한 사건 이므로 인정하지 아니한다. 
                if (curData.Date > a_Date)
                    continue;
                // 그날의 마디가와 목표가 목록을 가져 온다.
                SimpleDataList dataList = curData.DataList;
                for (int j = 0; j < dataList.Count; j++)
                {
                    EasyTrader.DataSet.SimpleData data = dataList[j];
                    if (data.CallCode == a_OpCode && data.CallType == a_Type)
                    {
                        a_OutVal = data.CallVal;
                        a_Center = data.CenterVal;
                        return true;
                    }
                    if (data.PutCode == a_OpCode && data.PutType == a_Type)
                    {
                        a_OutVal = data.PutVal;
                        a_Center = data.CenterVal;
                        return true;
                    }
                }
            }

            return false;
        }


        private SimpleDataList m_OptCrossValList = new SimpleDataList();
        public SimpleDataList OptCrossValList
        {
            get { return m_OptCrossValList; }
            set { m_OptCrossValList = value; }
        }

        public EasyTrader.DataSet.SimpleData FindOptCrossData(int a_Date, string a_PriceCode)
        {
            for (int i = 0; i < m_OptCrossValList.Count; i++)
            {
                EasyTrader.DataSet.SimpleData curData = m_OptCrossValList[i];
                if (a_Date == curData.Date && a_PriceCode == curData.PriceCode)
                    return curData;
            }

            return null;
        }

        public EasyTrader.DataSet.SimpleData FindOptCrossData(EasyTrader.DataSet.DayCrossData a_DayData, string a_PriceCode)
        {
            if (a_DayData == null)
                return null;

            SimpleDataList dataList = a_DayData.DataList;
            for (int i = 0; i < dataList.Count; i++)
            {
                EasyTrader.DataSet.SimpleData curData = dataList[i];
                if (curData.PriceCode == a_PriceCode)
                {
                    return curData;
                }
            }
            return null;
        }

        public EasyTrader.DataSet.DayCrossData FindOptCrossData(int a_Date)
        {
            for(int i = 0; i < m_OptCrossMonthData.Count; i++)
            {
                EasyTrader.DataSet.DayCrossData curDayData = m_OptCrossMonthData[i];
                if (curDayData.Date == a_Date)
                    return curDayData;
            }
            
            return null;
        }

        public EasyTrader.DataSet.SimpleData FindRecentOptCrossData(int a_Date, string a_PriceCode)
        {
            for (int i = 0; i < m_OptCrossValList.Count; i++)
            {
                EasyTrader.DataSet.SimpleData curData = m_OptCrossValList[i];
                if (curData.Date <= a_Date && a_PriceCode == curData.PriceCode)
                    return curData;
            }

            return null;
        }

        // 일반 마디가와 목표가를 가져 온다.
        public void FindRecentOptOuterCrossData(List<EasyTrader.DataSet.SimpleData> a_DataList)
        {
            int p = 0;
            for (int i = m_OptCrossMonthData.Count - 1; i >= 0; i--)
            {
                EasyTrader.DataSet.DayCrossData curDayData = m_OptCrossMonthData[i];
                SimpleDataList dataList = curDayData.DataList;
                for (int j = 0; j < dataList.Count; j++)
                {
                    EasyTrader.DataSet.SimpleData curData = dataList[j];
                    if (curData.PriceCode != curData.CenterVal)
                        a_DataList.Add(curData);
                }
                p++;
                if (p == 2)
                    break;
            }
        }

        // 일반 마디가와 목표가를 가져 온다.
        public void FindRecentOptOuterCrossData(List<EasyTrader.DataSet.SimpleData> a_DataList, string a_PriceCode)
        {
            int p = 0;
            for (int i = m_OptCrossMonthData.Count - 1; i >= 0; i--)
            {
                EasyTrader.DataSet.DayCrossData curDayData = m_OptCrossMonthData[i];
                SimpleDataList dataList = curDayData.DataList;
                for (int j = 0; j < dataList.Count; j++)
                {
                    EasyTrader.DataSet.SimpleData curData = dataList[j];
                    if (a_PriceCode == curData.PriceCode && curData.PriceCode != curData.CenterVal)
                        a_DataList.Add(curData);
                }
                p++;
                if (p == 2)
                    break;
            }
        }

        // 목표가와 마디가 중에 등가와 가격이 같은 것만 가져온다.
        public void FindRecentOptCenterCrossData(List<EasyTrader.DataSet.SimpleData> a_DataList)
        {
            for (int i = m_OptCrossMonthData.Count - 1; i >= 0; i--)
            {
                EasyTrader.DataSet.DayCrossData curDayData = m_OptCrossMonthData[i];
                SimpleDataList dataList = curDayData.DataList;
                for (int j = 0; j < dataList.Count; j++)
                {
                    EasyTrader.DataSet.SimpleData curData = dataList[j];
                    if (curData.PriceCode == curData.CenterVal)
                        a_DataList.Add(curData);
                }
            }
        }

        public void FindRecentOptCenterCrossData(List<EasyTrader.DataSet.SimpleData> a_DataList, string a_PriceCode)
        {
            for (int i = m_OptCrossMonthData.Count - 1; i >= 0; i--)
            {
                EasyTrader.DataSet.DayCrossData curDayData = m_OptCrossMonthData[i];
                SimpleDataList dataList = curDayData.DataList;
                for (int j = 0; j < dataList.Count; j++)
                {
                    EasyTrader.DataSet.SimpleData curData = dataList[j];
                    if (curData.PriceCode == curData.CenterVal && curData.PriceCode == a_PriceCode)
                        a_DataList.Add(curData);
                }
            }
        }


        public void FindOptCrossData(string a_PriceCode, List<EasyTrader.DataSet.SimpleData> a_OutList)
        {
            for (int i = 0; i < m_OptCrossValList.Count; i++)
            {
                EasyTrader.DataSet.SimpleData curData = m_OptCrossValList[i];
                if (a_PriceCode == curData.PriceCode)
                {
                    a_OutList.Add(curData);
                }
            }
        }
     

        private BarTableList m_OptChartTableList = new BarTableList();
        public BarTableList OptChartTableList
        {
            get { return m_OptChartTableList; }
            set { m_OptChartTableList = value; }
        }

        private BarTableList m_SimulOptChartTableList = new BarTableList();
        public BarTableList SimulOptChartTableList
        {
            get { return m_SimulOptChartTableList; }
            set { m_SimulOptChartTableList = value; }
        }



        private int m_OptChartTableCount = 0;
        public int OptChartTableCount
        {
            get { return m_OptChartTableCount; }
            set { m_OptChartTableCount = value; }
        }

        public void CreateOptTables()
        {
            for (int i = 0; i < DownLoader.OptChartCodeList.Count; i++)
            {
                EasyTrader.DataSet.CodePair pair = DownLoader.OptChartCodeList[i];
                EasyTrader.DataSet.BarDataTable table = new EasyTrader.DataSet.BarDataTable(pair.Code.ToString());
                m_OptChartTableList.Add(table);
            }

            m_OptChartTableCount = m_OptChartTableList.Count;
        }

        public void RenameOptTables()
        {
            for (int i = 0; i < DownLoader.OptChartCodeList.Count; i++)
            {
                EasyTrader.DataSet.CodePair pair = DownLoader.OptChartCodeList[i];
                EasyTrader.DataSet.BarDataTable table = m_OptChartTableList[i];
                if (table != null)
                {
                    // 모든 데이터를 없애준다.
                    table.Clear();
                    table.TableName = pair.Code.ToString();
                }
            }
        }

        // 옵션 행사가별 데이터 목록을 모두 없애준다.
        public void ClearOptDayDataList()
        {
            m_OptDayDataList.Clear();
        }

        public void ClearOptTables()
        {
            for (int i = 0; i < DownLoader.OptChartCodeList.Count; i++)
            {
                EasyTrader.DataSet.CodePair pair = DownLoader.OptChartCodeList[i];
                EasyTrader.DataSet.BarDataTable table = m_OptChartTableList[i];
                if (table != null)
                {
                    // 모든 데이터를 없애준다.
                    table.Clear();
                }
            }
        }

        public EasyTrader.DataSet.BarDataTable FindOptTable(string a_OpCode)
        {
            for (int i = 0; i < m_OptChartTableList.Count; i++)
            {
                EasyTrader.DataSet.BarDataTable table = m_OptChartTableList[i];
                if (a_OpCode == table.TableName)
                    return table;
            }
            return null;
        }

        public EasyTrader.DataSet.BarDataTable FindOptTableInCodeList(string a_OpCode)
        {
            /*
            for (int i = 0; i < m_OptChartTableList.Count; i++)
            {
                EasyTrader.DataSet.BarDataTable table = m_OptChartTableList[i];
                if (a_OpCode == table.TableName)
                    return table;
            }*/
            int codeIndex = DownLoader.FindOptChartCodeIndex(a_OpCode);
            if (codeIndex < 0)
                return null;
            EasyTrader.DataSet.BarDataTable table = m_OptChartTableList[codeIndex];

            return table;
        }

        public int FindOptTableIndex(string a_OpCode)
        {
            int index = -1;
            for (int i = 0; i < m_OptChartTableList.Count; i++)
            {
                EasyTrader.DataSet.BarDataTable table = m_OptChartTableList[i];
                if (a_OpCode == table.TableName)
                {
                    index = i;
                    break;
                }
            }
            return index;
        }

        // 이 함수는 그달의 옵션 가격에서 마디가격이 발생했는지를 찾는다. 
        // 마디가격이 발생했을 경우 참을 돌려주고 마디가와 목표가를 돌려준다.
        // 마디가격은 등가에서 한 행사가가 상대편의 고가를 넘어서고 상대편은 이편의 저가보다 내려갔을 때
        // 이긴 편의 저가가 마디가 진편의 고가가 목표가가 된다.
        // 그리고 반드시 이긴편의 다음 행사가에서 그날이나 다음날 교차가 일어나야 한다.
        public bool FindCallPutFullCross()
        {
            int remDays = DownLoader.GetElapDays();
            for (int i = remDays; i > -1; i--)
            {
                EasyTrader.DataSet.BarDataItem item = m_FutDayList[i];
                string callATM = DownLoader.GetCallAtm(item.Date);
                string putATM = DownLoader.GetPutAtm(item.Date);
                EasyTrader.DataSet.BarDataItemList dayData = FindOptDayData(callATM);
                if (dayData == null)
                {
                    int k = 0;
                    k = k + 1;
                }
                List<EasyTrader.DataSet.BarDataItem> dataList = dayData.DataList;
                EasyTrader.DataSet.BarDataItem callDayItem = null;
                // 해당 날짜의 정보를 찾는다.
                for (int j = 0; j < dataList.Count; j++)
                {
                    callDayItem = dataList[j];
                    if (callDayItem.Date.ToString() == item.Date.ToString())
                        break;
                }

                dayData = FindOptDayData(putATM);
                dataList = dayData.DataList;
                EasyTrader.DataSet.BarDataItem putDayItem = null;
                // 해당 날짜의 정보를 찾는다.
                for (int j = 0; j < dataList.Count; j++)
                {
                    putDayItem = dataList[j];
                    if (putDayItem.Date.ToString() == item.Date.ToString())
                        break;
                }
                if (callDayItem.Date.ToString() == putDayItem.Date.ToString())
                {
                    double callOpen = Convert.ToDouble(callDayItem.Open.ToString());
                    double callHigh = Convert.ToDouble(callDayItem.High.ToString());
                    double callLow = Convert.ToDouble(callDayItem.Low.ToString());
                    double callClose = Convert.ToDouble(callDayItem.Close.ToString());

                    double putOpen = Convert.ToDouble(putDayItem.Open.ToString());
                    double putHigh = Convert.ToDouble(putDayItem.High.ToString());
                    double putLow = Convert.ToDouble(putDayItem.Low.ToString());
                    double putClose = Convert.ToDouble(putDayItem.Close.ToString());

                    if (callOpen < putOpen)
                    {
                        // 콜이 이겼을 경우 상위 행사가에서 교차가 일어나야 한다.
                        if (callHigh > putHigh && putLow < callLow)
                        {
                            string callUpCode = "";
                            bool result = DownLoader.GetCallUpDownCode(callATM, 1, out callUpCode);

                            if (result == true)
                            {
                                string priceCode = callUpCode.Substring(callUpCode.Length - 3, 3);
                                result = FindCallPutCross(Convert.ToInt32(item.Date), priceCode);
                                if (result == true)
                                {
                                    int p = 0;
                                    p = p + 1;
                                }
                            }
                        }
                    }
                    else if (putOpen < callOpen)
                    {
                        // 풋이 이겼을 경우 하위 행사가에서 교차가 일어나야 한다.
                        if (putHigh > callHigh && callLow < putLow)
                        {
                            string putUpCode = "";
                            bool result = DownLoader.GetPutUpDownCode(putATM, -1, out putUpCode);

                            if (result == true)
                            {
                                string priceCode = putUpCode.Substring(putUpCode.Length - 3, 3);
                                result = FindCallPutCross(Convert.ToInt32(item.Date), priceCode);
                                if (result == true)
                                {
                                    int p = 0;
                                    p = p + 1;
                                }
                            }
                        }
                    }
                }
            }

            return true;
        }


        private bool FindCallPutCross(int a_Date, string a_PriceCode)
        {
            EasyTrader.DataSet.CodeTable code = DownLoader.FindCallPutCodeList(a_PriceCode);
            if (code == null)
                return false;

            // 해당 코드의 날짜별 
            EasyTrader.DataSet.BarDataItemList dayData = FindOptDayData(code.CallCode);
            List<EasyTrader.DataSet.BarDataItem> dataList = dayData.DataList;
            EasyTrader.DataSet.BarDataItem callDayItem = null;
            // 해당 날짜의 정보를 찾는다.
            for (int j = 0; j < dataList.Count; j++)
            {
                callDayItem = dataList[j];
                if (callDayItem.Date.ToString() == a_Date.ToString())
                    break;
            }
            if (callDayItem == null)
                return false;


            dayData = FindOptDayData(code.PutCode);
            dataList = dayData.DataList;
            EasyTrader.DataSet.BarDataItem putDayItem = null;
            // 해당 날짜의 정보를 찾는다.
            for (int j = 0; j < dataList.Count; j++)
            {
                putDayItem = dataList[j];
                if (putDayItem.Date.ToString() == a_Date.ToString())
                    break;
            }
            if (putDayItem == null)
                return false;

            if (callDayItem.Date.ToString() == putDayItem.Date.ToString())
            {
                double callOpen = Convert.ToDouble(callDayItem.Open.ToString());
                double callHigh = Convert.ToDouble(callDayItem.High.ToString());
                double callLow = Convert.ToDouble(callDayItem.Low.ToString());
                double callClose = Convert.ToDouble(callDayItem.Close.ToString());

                double putOpen = Convert.ToDouble(putDayItem.Open.ToString());
                double putHigh = Convert.ToDouble(putDayItem.High.ToString());
                double putLow = Convert.ToDouble(putDayItem.Low.ToString());
                double putClose = Convert.ToDouble(putDayItem.Close.ToString());

                if (callOpen < putOpen)
                {
                    if (callHigh > putLow)
                    {
                        return true;
                    }
                }
                else if (putOpen < callOpen)
                {
                    if (putHigh > callLow)
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        public EasyTrader.DataSet.BarDataItemList FindOptDayData(string a_OpCode)
        {
            for (int i = 0; i < m_OptDayDataList.Count; i++)
            {
                EasyTrader.DataSet.BarDataItemList curCol = m_OptDayDataList[i];
                object code = curCol.Code;
                if (code.ToString() == a_OpCode)
                {
                    return curCol;
                }
            }

            return null;
        }

#region DDE Data List
        // 하루하루 DDE 데이터를 모아 놓은 목록이다.
        private OptMonthData m_OptionMonthData = new OptMonthData();
        public OptMonthData OptionMonthData
        {
            get { return m_OptionMonthData; }
            set { m_OptionMonthData = value; }
        }

        // 한달 분량의 저마기목고에 대한 객체 목록을 만든다.
        private void CreateMonthData()
        {
            m_OptionMonthData.Clear();
            int dayCount = 0;
            int exDay = DownLoader.FindRecentExpDay(DownLoader.CurDay);
            int baseDay = exDay + 1;
            for (int i = 0; i < m_FutDayList.Count; i++)
            {
                EasyTrader.DataSet.BarDataItem item = m_FutDayList[i];
                int curDay = Convert.ToInt32(item.Date.ToString());
                if (curDay < baseDay)
                    break;
                dayCount++;
                EasyTrader.Option.DDEDayData newDayData = new EasyTrader.Option.DDEDayData();
                newDayData.Date = item.Date;
                m_OptionMonthData.Add(newDayData);
                //Console.WriteLine(curDay.ToString());
                //Console.WriteLine(dayCount.ToString());

                for (int j = 0; j < DownLoader.PriceCodeList.Count; j++)
                {
                    EasyTrader.Option.DDEData newPriceData = new EasyTrader.Option.DDEData();
                    newPriceData.PriceCode = DownLoader.PriceCodeList[j];
                    //Console.WriteLine(newPriceData.PriceCode);
                    newDayData.CollectionList.Add(newPriceData);
                }
            }
        }

        private void CreateMonthData(int a_CurDay)
        {
            int dayCount = 0;
            int exDay = DownLoader.FindRecentExpDay(a_CurDay);
            int baseDay = exDay + 1;
            m_OptionMonthData.Clear();
            for (int i = 0; i < m_FutDayList.Count; i++)
            {
                EasyTrader.DataSet.BarDataItem item = m_FutDayList[i];
                int curDay = Convert.ToInt32(item.Date.ToString());
                if (curDay < baseDay)
                    break;
                dayCount++;
                EasyTrader.Option.DDEDayData newDayData = new EasyTrader.Option.DDEDayData();
                newDayData.Date = item.Date;
                m_OptionMonthData.Add(newDayData);
                //Console.WriteLine(curDay.ToString());
                //Console.WriteLine(dayCount.ToString());

                for (int j = 0; j < DownLoader.PriceCodeList.Count; j++)
                {
                    EasyTrader.Option.DDEData newPriceData = new EasyTrader.Option.DDEData();
                    newPriceData.PriceCode = DownLoader.PriceCodeList[j];
                    //Console.WriteLine(newPriceData.PriceCode);
                    newDayData.CollectionList.Add(newPriceData);
                }
            }
        }

        private void FillDDEMonthData()
        {
            for (int i = 0; i < m_OptDayDataList.Count; i++)
            {
                EasyTrader.DataSet.BarDataItemList curCol = m_OptDayDataList[i];
                List<EasyTrader.DataSet.BarDataItem> dataList = curCol.DataList;
                object code = curCol.Code;
                OptMonthData opMonData = m_OptionMonthData;
                for (int j = 0; j < opMonData.Count; j++)
                {
                    EasyTrader.Option.DDEDayData dayDataCol = opMonData[j];
                    object curDay = dayDataCol.Date;

                    double rHigh, rLow;
                    FindHighLow(dataList, Convert.ToInt32(curDay.ToString()), out rHigh, out rLow);
                    object baseVal = FindBase(dataList);
                    object curOpen, curHigh, curLow, curClose;
                    FindCurDayVal(Convert.ToInt32(curDay.ToString()), dataList, out curHigh, out curLow, out curOpen, out curClose);
                    object preClose, preHigh, preLow, preOpen;
                    FindPreDayVal(Convert.ToInt32(curDay.ToString()), dataList, out preHigh, out preLow, out preClose, out preOpen);

                    EasyTrader.Option.DDEData curDataCol = FindDDEData(dayDataCol, code);
                    if (curDataCol != null)
                    {
                        string sideCode = code.ToString().Substring(0, 1);
                        EasyTrader.Option.DDEDataItem dataItem = curDataCol.DataItem;
                        if (sideCode == "2")
                        {
                            dataItem.CallBase = baseVal;
                            dataItem.CallMHigh = rHigh;
                            dataItem.CallMLow = rLow;
                            dataItem.CallCurClose = curClose;
                            dataItem.CallCurOpen = curOpen;
                            dataItem.CallCurHigh = curHigh;
                            dataItem.CallCurLow = curLow;
                            dataItem.CallPreClose = preClose;
                            dataItem.CallPreHigh = preHigh;
                            dataItem.CallPreLow = preLow;
                            dataItem.CallPreOpen = preOpen;
                            curDataCol.CallCode = code;
                        }
                        else if (sideCode == "3")
                        {
                            dataItem.PutBase = baseVal;
                            dataItem.PutMHigh = rHigh;
                            dataItem.PutMLow = rLow;
                            dataItem.PutCurClose = curClose;
                            dataItem.PutCurOpen = curOpen;
                            dataItem.PutCurHigh = curHigh;
                            dataItem.PutCurLow = curLow;
                            dataItem.PutPreClose = preClose;
                            dataItem.PutPreHigh = preHigh;
                            dataItem.PutPreLow = preLow;
                            dataItem.PutPreOpen = preOpen;
                            curDataCol.PutCode = code;
                        }
                    }
                }
            }

            //EasyTrader.Option.DDEDayDataCollection curDayCol = FindDDEDayDataCol(DownLoader.CurDay);
            //DDEForm.SetDayCol(curDayCol);

            //m_MonthDataFilled = true;
        }

        public EasyTrader.Option.DDEData FindDDEData(object a_CurDay, object a_OpCode)
        {
            string code = a_OpCode.ToString();
            code = code.Substring(code.Length - 3, 3);
            for (int i = 0; i < m_OptionMonthData.Count; i++)
            {
                EasyTrader.Option.DDEDayData curCol = m_OptionMonthData[i];
                if (Convert.ToInt32(curCol.Date) == Convert.ToInt32(a_CurDay))
                {
                    DDEDataList dataList = curCol.CollectionList;
                    for (int j = 0; j < dataList.Count; j++)
                    {
                        EasyTrader.Option.DDEData curList = dataList[j];
                        if (curList.PriceCode.ToString() == code)
                        {
                            return curList;
                        }
                    }
                }
            }

            return null;
        }

        public EasyTrader.Option.DDEData FindDDEData(EasyTrader.Option.DDEDayData curCol, object a_OpCode)
        {
            string code = a_OpCode.ToString();
            code = code.Substring(code.Length - 3, 3);
            DDEDataList dataList = curCol.CollectionList;
            for (int j = 0; j < dataList.Count; j++)
            {
                EasyTrader.Option.DDEData curList = dataList[j];
                if (curList.PriceCode.ToString() == code)
                {
                    return curList;
                }
            }

            return null;
        }
#endregion
        

        private void FindPreDayVal(int a_CurDay, List<EasyTrader.DataSet.BarDataItem> a_DataList, out object a_High, out object a_Low, out object a_Close, out object a_Open)
        {
            int curPos = 0;
            EasyTrader.DataSet.BarDataItem item = null;
            for (int i = 0; i < a_DataList.Count; i++)
            {
                item = a_DataList[i];
                int curDay = Convert.ToInt32(item.Date.ToString());
                if (curDay == a_CurDay)
                {
                    curPos = i + 1;
                    break;
                }
            }

            if (curPos > a_DataList.Count - 1)
                curPos = a_DataList.Count - 1;

            item = a_DataList[curPos];
            a_High = item.High;
            a_Low = item.Low;
            a_Close = item.Close;
            a_Open = item.Open;
        }

        private void FindCurDayVal(int a_CurDay, List<EasyTrader.DataSet.BarDataItem> a_DataList, out object a_High, out object a_Low, out object a_Open, out object a_Close)
        {
            int curPos = 0;
            EasyTrader.DataSet.BarDataItem item = null;
            for (int i = 0; i < a_DataList.Count; i++)
            {
                item = a_DataList[i];
                int curDay = Convert.ToInt32(item.Date.ToString());
                if (curDay == a_CurDay)
                {
                    curPos = i;
                    break;
                }
            }

            item = a_DataList[curPos];
            a_High = item.High;
            a_Low = item.Low;
            a_Open = item.Open;
            a_Close = item.Close;
        }

        // 기준가는 만기날 다음날 저가로 한다. 
        // 단, 새로 탄생하는 행사가에 대하여는 탄생한 날의 저가를 기준가로 잡는다.
        private object FindBaseVal(List<EasyTrader.DataSet.BarDataItem> a_DataList)
        {
            EasyTrader.DataSet.BarDataItem item = a_DataList[a_DataList.Count - 1];
            object low = item.Low;
            return low;
        }

        // 기준가는 만기날 다음날 저가로 한다. 
        // 단, 새로 탄생하는 행사가에 대하여는 탄생한 날의 저가를 기준가로 잡는다.
        private object FindBase(List<EasyTrader.DataSet.BarDataItem> a_DataList)
        {
            // 만기날 다음 날을 찾는다.
            int baseDay = DownLoader.FindRecentExpDay(DownLoader.CurDay) + 1;
            object low = null;
            for (int i = 0; i < a_DataList.Count; i++)
            {
                EasyTrader.DataSet.BarDataItem item = a_DataList[i];
                int day = Convert.ToInt32(item.Date);
                low = item.Low;
                // 기준일이면 더 이상 검사를 하지 않는다.
                if (day == baseDay)
                    break;
            }
            
            return low;
        }


        public int FindFutInvDiv(int a_CurIndex, int a_Mode, ref double min, ref double max, ref double close)
        {
            EasyTrader.DataSet.FutOptChartTable curTable = GetFutOptChartTable();
            if (curTable == null || a_CurIndex < 0)
                return GlobalVar.StateNone;

            return GlobalVar.FindInvDiv(a_CurIndex, curTable, ref min, ref max, ref close, a_Mode);
        }

        public int FindHighLowIndex(int a_StartIndex, int a_EndIndex, ref int a_HighIndex, ref int a_LowIndex, ref double a_Min, ref double a_Max, ref double a_Amp)
        {


            EasyTrader.DataSet.FutOptChartTable curTable = GetFutOptChartTable();
            if (curTable == null || a_StartIndex < 0 || a_EndIndex < 0 || a_StartIndex > a_EndIndex)
                return -1;

            if (curTable.GetRowCount() == 0)
                return -1;

            if (a_StartIndex > curTable.GetRowCount() - 1)
                a_StartIndex = curTable.GetRowCount() - 1;

            if (a_EndIndex > curTable.GetRowCount() - 1)
                a_EndIndex = curTable.GetRowCount() - 1;

            DataRow row = curTable.Rows[a_StartIndex];
            double high = Convert.ToDouble(row["고가"]);
            double low = Convert.ToDouble(row["저가"]);
            double open = Convert.ToDouble(row["시가"]);

            //double max = open;
            //double min = open;
            a_Min = open;
            a_Max = open;
            for (int i = a_StartIndex; i <= a_EndIndex; i++)
            {
                row = curTable.Rows[i];
                high = Convert.ToDouble(row["고가"]);
                low = Convert.ToDouble(row["저가"]);
                if (high > a_Max)
                {
                    a_Max = high;
                    a_HighIndex = i;
                }
                if (low < a_Min)
                {
                    a_Min = low;
                    a_LowIndex = i;
                }
            }

            return Math.Max(a_HighIndex, a_LowIndex);
        }

        private void FindHighLow(List<EasyTrader.DataSet.BarDataItem> a_DataList, int a_CurDay, out double a_High, out double a_Low)
        {
            a_High = -9999999.0;
            a_Low = 9999999.0;
            // 만기날 다음 날을 찾는다.
            int baseDay = DownLoader.FindRecentExpDay(DownLoader.CurDay) + 1;
            // 만기날 다음 날 부터 영업일 수를 계산한다. 이 날짜는 현재 날짜를 포함한다.
            int openedDays = DownLoader.GetOpenedDays(a_CurDay, baseDay);
            // a_DataList는 이 행사가에 대한 날짜별 시고저종을 가지고 있다. 최근날짜가 먼저오고 과거 날짜가 늦게 온다.
            for (int i = 0; i < a_DataList.Count; i++)
            {
                EasyTrader.DataSet.BarDataItem item = a_DataList[i];
                int day = Convert.ToInt32(item.Date);
                if (openedDays > 1) // 기준일을 지난 이후의 날들
                {
                    // 이날 새로운 행사가가 탄생한 것은 월고와 월저가 없으므로 그날 당일의 저가와 고가를 전달해 준다.
                    if (a_DataList.Count <= 1)
                    {
                        a_High = Convert.ToDouble(item.High.ToString());
                        a_Low = Convert.ToDouble(item.Low.ToString());
                    }
                    else // 기준일에서 수일 지난 것들은 당일 전날까지 고가와 저가를 전달해 준다. 
                    {
                        if (day < a_CurDay)
                        {
                            //Console.WriteLine(day.ToString());
                            double high = Convert.ToDouble(item.High.ToString());
                            double low = Convert.ToDouble(item.Low.ToString());
                            if (high > a_High)
                                a_High = high;
                            if (low < a_Low)
                                a_Low = low;
                        }
                    }
                }
                else // 기준일 당일
                {
                    if (day <= a_CurDay)
                    {
                        //Console.WriteLine(day.ToString());
                        double high = Convert.ToDouble(item.High.ToString());
                        double low = Convert.ToDouble(item.Low.ToString());
                        if (high > a_High)
                            a_High = high;
                        if (low < a_Low)
                            a_Low = low;
                    }
                }

                // 기준일일 경우 탈출한다.
                if (day == baseDay)
                    break;
            }
        }

        public EasyTrader.Option.DDEDayData FindNextDDEDayData(object a_CurDay)
        {
            int dayIndex = 0;
            for (int i = 0; i < m_OptionMonthData.Count; i++)
            {
                EasyTrader.Option.DDEDayData curCol = m_OptionMonthData[i];
                if (Convert.ToInt32(curCol.Date) == Convert.ToInt32(a_CurDay))
                {
                    dayIndex = i;
                    break;
                }
            }

            dayIndex = dayIndex - 1;
            if (dayIndex > m_OptionMonthData.Count - 1)
                dayIndex = m_OptionMonthData.Count - 1;
            if (dayIndex < 0)
                dayIndex = 0;

            return m_OptionMonthData[dayIndex];
        }

        public EasyTrader.Option.DDEDayData FindPrevDDEDayData(object a_CurDay)
        {
            int dayIndex = 0;
            for (int i = 0; i < m_OptionMonthData.Count; i++)
            {
                EasyTrader.Option.DDEDayData curCol = m_OptionMonthData[i];
                if (Convert.ToInt32(curCol.Date) == Convert.ToInt32(a_CurDay))
                {
                    dayIndex = i;
                    break;
                }
            }

            dayIndex = dayIndex + 1;
            if (dayIndex > m_OptionMonthData.Count - 1)
                dayIndex = m_OptionMonthData.Count - 1;
            if (dayIndex < 0)
                dayIndex = 0;

            return m_OptionMonthData[dayIndex];
        }

        public EasyTrader.Option.DDEDayData FindDDEDayData(object a_CurDay)
        {
            int dayIndex = 0;
            for (int i = 0; i < m_OptionMonthData.Count; i++)
            {
                EasyTrader.Option.DDEDayData curCol = m_OptionMonthData[i];
                if (Convert.ToInt32(curCol.Date) == Convert.ToInt32(a_CurDay))
                {
                    dayIndex = i;
                    break;
                }
            }
            return m_OptionMonthData[dayIndex];
        }


        public void FindLastOpenDay(int a_CurDate, out int a_OpenDay, out int a_PreOpenDay)
        {
            a_OpenDay = 0;
            a_PreOpenDay = 0;
            for (int i = 0; i < m_FutDayList.Count; i++)
            {
                EasyTrader.DataSet.BarDataItem item = m_FutDayList[i];
                int curDate = Convert.ToInt32(item.Date);
                if (curDate <= a_CurDate)
                {
                    a_OpenDay = curDate;
                    item = m_FutDayList[i + 1];
                    a_PreOpenDay = Convert.ToInt32(item.Date);
                    break;
                }
            }
        }

        // 주어진 날짜에 대해서 등가를 찾아 준다.
        // 등가는 종가에 결정되지만 시가로 찾아서 그날의 변화를 살펴 봐야 하므로
        // 선물의 시가를 중심으로 옵션 등가를 찾는다. 
        public double CalcAtm(object a_CurDay)
        {
            object dayOpen = "";
            // 먼저 날짜에 맞는 선물 데이터를 찾아 시작값을 가져온다.
            for (int i = 0; i < m_FutDayList.Count; i++)
            {
                EasyTrader.DataSet.BarDataItem item = m_FutDayList[i];
                object date = item.Date;
                if (Convert.ToInt32(date) == Convert.ToInt32(a_CurDay))
                {
                    dayOpen = item.Open;
                    break;
                }
            }

            double openVal = Convert.ToDouble(dayOpen);
            double atm = 0.0;
            for (int j = 0; j < m_DownLoader.PriceCodeList.Count; j++)
            {
                string code = m_DownLoader.PriceCodeList[j];
                string endCode = code.Substring(code.Length - 1, 1);
                string price = code;
                if (endCode == "2" || endCode == "7")
                    price += ".5";
                // 하나의 행사가에 대하여 위 아래로 1.25 범위로 조사한다.
                // 이때 작은 부분의 경계선은 포함하지 않으며
                // 큰 부분의 경계선은 포함한다.
                // 그 이유는 경계선 상에 값이 있을 때 더 작은 놈이 선택되기 때문이다.
                double low = Convert.ToDouble(price) - 1.25;
                double high = Convert.ToDouble(price) + 1.25;
                if (openVal > low && openVal <= high)
                {
                    atm = Convert.ToDouble(price);
                    break;
                }
            }

            return atm;
        }


        // 주어진 날짜에 대해서 등가를 찾아 준다.
        // 등가는 종가에 결정되지만 시가로 찾아서 그날의 변화를 살펴 봐야 하므로
        // 선물의 시가를 중심으로 옵션 등가를 찾는다. 
        public double CalcAtm()
        {
            EasyTrader.DataSet.FutOptChartTable table = GetFutOptChartTable();
            if (table == null || table.GetRowCount() == 0)
                return -1.0;
            int rowCount = table.GetRowCount();
            DataRow row = table.Rows[rowCount - 1];
            object dayOpen = row["시가"];
            double openVal = Convert.ToDouble(dayOpen);
            double atm = 0.0;
            for (int j = 0; j < m_DownLoader.PriceCodeList.Count; j++)
            {
                string code = m_DownLoader.PriceCodeList[j];
                string endCode = code.Substring(code.Length - 1, 1);
                string price = code;
                if (endCode == "2" || endCode == "7")
                    price += ".5";
                // 하나의 행사가에 대하여 위 아래로 1.25 범위로 조사한다.
                // 이때 작은 부분의 경계선은 포함하지 않으며
                // 큰 부분의 경계선은 포함한다.
                // 그 이유는 경계선 상에 값이 있을 때 더 작은 놈이 선택되기 때문이다.
                double low = Convert.ToDouble(price) - 1.25;
                double high = Convert.ToDouble(price) + 1.25;
                if (openVal > low && openVal <= high)
                {
                    atm = Convert.ToDouble(price);
                    break;
                }
            }

            return atm;
        }


        public void MakeOptPastCodeList(List<EasyTrader.DataSet.CodePair> a_OutList, int a_CurDay)
        {
            a_OutList.Clear();

            // 콜 코드를 먼저 만들어 준다.
            string callATM = DownLoader.GetCallAtm();
            if (callATM == "")
                callATM = DownLoader.GetCallAtm(a_CurDay);

            int atmRow = 0;
            if (callATM != "")
            {
                for (int i = 0; i < DownLoader.CallPriceCodeList.Count; i++)
                {
                    EasyTrader.DataSet.CodeTable code = DownLoader.CallPriceCodeList[i];
                    if (callATM == code.Code)
                    {
                        atmRow = i;
                        break;
                    }
                }
                int start = atmRow - GlobalVar.OptChartRange;
                int end = atmRow + GlobalVar.OptChartRange;
                for (int i = start; i <= end; i++)
                {
                    EasyTrader.DataSet.CodeTable code = DownLoader.CallPriceCodeList[i];
                    EasyTrader.DataSet.CodePair pair = new EasyTrader.DataSet.CodePair();
                    pair.Date = a_CurDay;
                    pair.Code = code.Code;
                    a_OutList.Add(pair);
                }
            }

            // 풋 코드는 항상 뒤에 만들어 준다. 
            string putATM = DownLoader.GetPutAtm();
            if (putATM == "")
                putATM = DownLoader.GetPutAtm(a_CurDay);
            if (putATM != "")
            {
                for (int i = 0; i < DownLoader.PutPriceCodeList.Count; i++)
                {
                    EasyTrader.DataSet.CodeTable code = DownLoader.PutPriceCodeList[i];
                    if (putATM == code.Code)
                    {
                        atmRow = i;
                        break;
                    }
                }
                int start = atmRow - GlobalVar.OptChartRange;
                int end = atmRow + GlobalVar.OptChartRange;
                for (int i = start; i <= end; i++)
                {
                    EasyTrader.DataSet.CodeTable code = DownLoader.PutPriceCodeList[i];
                    EasyTrader.DataSet.CodePair pair = new EasyTrader.DataSet.CodePair();
                    pair.Date = a_CurDay;
                    pair.Code = code.Code;
                    a_OutList.Add(pair);
                }
            }
            //m_EasyTraderDataSet.MakeOptPastCodeList(m_OptChartCodeList, Convert.ToInt32(m_CurDay));
        }

        /*
        public void MakeOptPastCodeList(List<EasyTrader.DataSet.CodePair> a_OutList, int a_CurDay)
        {
            a_OutList.Clear();
            string callATM = DownLoader.GetCallAtm();
            if (callATM == "")
                callATM = DownLoader.GetCallAtm(a_CurDay);

            string centerPrice = callATM.Substring(callATM.Length - 3, 3);
            string endCode = centerPrice.Substring(centerPrice.Length - 1, 1);
            string price = centerPrice;
            if (endCode == "2" || endCode == "7")
                price += ".5";

            centerPrice = price;

            for (int j = 0; j < DownLoader.CenterPriceCodeList.Count; j++)
            {
                EasyTrader.DataSet.CodeTable opCode = DownLoader.CenterPriceCodeList[j];
                string code = opCode.Code;
                price = code.Substring(code.Length - 3, 3);
                endCode = price.Substring(price.Length - 1, 1);
                string curPrice = price;
                if (endCode == "2" || endCode == "7")
                    curPrice += ".5";
                double delta = Math.Abs(Convert.ToDouble(curPrice) - Convert.ToDouble(centerPrice));
                if (delta <= GlobalVar.MonitorRange)
                {
                    EasyTrader.DataSet.CodePair pair = new EasyTrader.DataSet.CodePair();
                    pair.Date = a_CurDay;
                    pair.Code = opCode.Code;
                    a_OutList.Add(pair);
                }
            }
        }*/

#region Option Data List
        // 옵션 차트 데이터 목록 - 옵션은 행사가에 따라 차트 데이터가 필요하므로 여러개의 데이터 목록이 필요하다.
        private BarDataCollection m_OptChartDataList = new BarDataCollection();
        public BarDataCollection OptChartDataList
        {
            get { return m_OptChartDataList; }
            set { m_OptChartDataList = value; }
        }


        // 행사가 별로 일일 시고저종을 날짜순으로 모아 놓은 데이터 목록이다.
        // 각 항목을 구분하는 것은 행사가이다. 인덱스가 달라지면 행사가가 달라진다.
        private BarDataCollection m_OptDayDataList = new BarDataCollection();
        public BarDataCollection OptDayDataList
        {
            get { return m_OptDayDataList; }
            set { m_OptDayDataList = value; }
        }

        private BarDataList m_FutDayList = new BarDataList();
        public BarDataList FutDayList
        {
            get { return m_FutDayList; }
            set { m_FutDayList = value; }
        }

        private EasyTrader.DataSet.DownloadCenter m_DownLoader = null;
        public EasyTrader.DataSet.DownloadCenter DownLoader
        {
            get { return m_DownLoader; }
            set { m_DownLoader = value; }
        }

#endregion

        // 이 함수는 현재 시스템의 기준가를 찾는다.
        public double FindTodayBase()
        {
            EasyTrader.DataSet.CmeDailyTable curTable = GetCmeDailyTable();
            int rowCount = curTable.GetRowCount();
            if (rowCount == 0)
                return 0;
            double baseVal = 0;
            for (int i = rowCount - 1; i >= 0; i--)
            {
                DataRow row = curTable.Rows[i];
                int date = Convert.ToInt32(row["날짜"]);
                if (date == GlobalVar.PreDateToInt())
                {
                    double high = Convert.ToDouble(row["고가"]);
                    double low = Convert.ToDouble(row["저가"]);
                    double cmeHigh = Convert.ToDouble(row["CME고가"]);
                    double cmeLow = Convert.ToDouble(row["CME저가"]);
                    double max = Math.Max(high, cmeHigh);
                    double min = Math.Min(low, cmeLow);
                    baseVal = min + (max - min) / 2;
                    break;
                }
            }
            return baseVal;
        }

        public void MakeDailyAmp()
        {
            // 먼저 테이블을 비워준다.
            EasyTrader.DataSet.FutureDailyAmpTable curTable = GetFutureDailyAmpTable();
            if (curTable.GetRowCount() > 0)
            {
                curTable.Clear();
            }
            // 주간 일자별 테이블을 불러와 데이터를 넣어준다.
            EasyTrader.DataSet.FutOptDailyTable dayTable = GetFutOptDailyTable();
            if (dayTable != null)
            {
                for (int i = 0; i < dayTable.GetRowCount(); i++)
                {
                    DataRow row = dayTable.Rows[i];
                    object[] dataRow = new object[5];
                    dataRow[0] = i;
                    dataRow[1] = row["날짜"];
                    dataRow[2] = row["고가"];
                    dataRow[3] = row["저가"];
                    dataRow[4] = Convert.ToDouble(row["고가"]) - Convert.ToDouble(row["저가"]);
                    curTable.AddRow(dataRow);
                }
            }

            EasyTrader.DataSet.CmeDailyTable cmeTable = GetCmeDailyTable();
            if (cmeTable != null)
            {
                int cmeRowCount = cmeTable.GetRowCount();
                if (cmeRowCount == 0)
                    return;
                int cmeCount = cmeTable.GetRowCount();
                int rowCount = curTable.GetRowCount();
                for (int i = 0; i < cmeCount; i++)
                {
                    DataRow cmeRow = cmeTable.Rows[i];
                    int cmeDate = Convert.ToInt32(cmeRow["날짜"]);
                    double cmeHigh = Convert.ToDouble(cmeRow["CME고가"]);
                    double cmeLow = Convert.ToDouble(cmeRow["CME저가"]);
                    for (int j = 0; j < rowCount; j++)
                    {
                        DataRow curRow = curTable.Rows[j];
                        int curDate = Convert.ToInt32(curRow["날짜"]);
                        double curHigh = Convert.ToDouble(curRow["고가"]);
                        double curLow = Convert.ToDouble(curRow["저가"]);
                        double amp = curHigh - curLow;
                        if (cmeDate == curDate)
                        {
                            if (cmeHigh != 0 && cmeHigh > curHigh)
                                curRow["고가"] = cmeHigh;
                            if (cmeLow != 0 && cmeLow < curLow)
                                curRow["저가"] = cmeLow;
                            curRow["진폭"] = Math.Max(curHigh, cmeHigh) - Math.Min(curLow, cmeLow);
                            break;
                        }
                    }
                }
            }
        }

        public void MakeCmeDailyAmp()
        {
            // 먼저 테이블을 비워준다.
            EasyTrader.DataSet.FutureDailyAmpTable curTable = GetFutureDailyAmpTable();
            if (curTable.GetRowCount() > 0)
            {
                curTable.Clear();
            }
            // 주간 일자별 테이블을 불러와 데이터를 넣어준다.
            EasyTrader.DataSet.CmeDailyTable cmeTable = GetCmeDailyTable();
            if (cmeTable != null)
            {
                for (int i = 0; i < cmeTable.GetRowCount(); i++)
                {
                    DataRow row = cmeTable.Rows[i];
                    int cmeDate = Convert.ToInt32(row["날짜"]);
                    double dayHigh = Convert.ToDouble(row["고가"]);
                    double dayLow = Convert.ToDouble(row["저가"]);
                    double cmeHigh = Convert.ToDouble(row["CME고가"]);
                    double cmeLow = Convert.ToDouble(row["CME저가"]);
                    object[] dataRow = new object[5];
                    dataRow[0] = i;
                    dataRow[1] = cmeDate;
                    if (cmeHigh != 0 && cmeLow != 0)
                    {
                        dataRow[2] = Math.Max(dayHigh, cmeHigh);
                        dataRow[3] = Math.Min(dayLow, cmeLow);
                        dataRow[4] = Math.Max(dayHigh, cmeHigh) - Math.Min(dayLow, cmeLow);
                    }
                    else
                    {
                        dataRow[2] = dayHigh;
                        dataRow[3] = dayLow;
                        dataRow[4] = dayHigh - dayLow;
                    }
                    curTable.AddRow(dataRow);
                }
            }
        }


        // 현재 테이블들을 XML로 저장한다.
        public void SaveTablesToXML()
        {
            int tableCount = this.Tables.Count;
            for (int i = 0; i < tableCount; i++)
            {
                EasyTrader.DataSet.ETDataTable curTable = (EasyTrader.DataSet.ETDataTable)Tables[i];
                curTable.SaveTableToXml();
            }
        }

        // XML에서 자료를 가져온다.
        public void ReadTablesFromXML(DateTime a_DateTime)
        {
            int tableCount = this.Tables.Count;
            for (int i = 0; i < tableCount; i++)
            {
                EasyTrader.DataSet.ETDataTable curTable = (EasyTrader.DataSet.ETDataTable)Tables[i];
                curTable.ReadFromXml(a_DateTime);
            }
        }
        //System.Windows.Forms.DataVisualization.Charting.Chart m_FutOptChart = new System.Windows.Forms.DataVisualization.Charting.Chart();


#region TableBuffer
        public object[] FutureCurOnlyTableBuffer = new object[GlobalVar.FutureCurOnlyTableColSize];
        public object[] FutureJpBidTableBuffer = new object[GlobalVar.FutureJpBidTableColSize];
        public object[] CPSvr8111STableBuffer = new object[GlobalVar.CPSvr8111STableColSize];
        public object[] CPSvrNew7221SKospiTableBuffer = new object[GlobalVar.CPSvrNew7221SKospiTableColSize];
        public object[] CPSvrNew7221SFutureTableBuffer = new object[GlobalVar.CPSvrNew7221SFutureTableColSize];
        public object[] CPSvrNew7221SOptionTableBuffer = new object[GlobalVar.CPSvrNew7221SOptionTableColSize];
        public object[] CmeCurrTableBuffer = new object[GlobalVar.CmeCurrTableColSize];
#endregion
        public ETDataSet(string a_Name)
            : base(a_Name)
        {
            CreateTables();
        }



        public void CreateTables()
        {
            // 여기서 각각의 테이블을 생성한다.
            DataTable curTable = new EasyTrader.DataSet.FutOptChartTable("FutOptChart");
            AddTable(curTable);
            curTable = new FutureCurOnlyTable("FutureCurOnly");
            AddTable(curTable);
            curTable = new FutureMstTable("FutureMst");
            AddTable(curTable);
            curTable = new FutureJpBidTable("FutureJpBid");
            AddTable(curTable);
            curTable = new CPSvrNew7221Table("CPSvrNew7221");
            AddTable(curTable);
            curTable = new CPSvr8111STable("CPSvr8111S");
            AddTable(curTable);
            curTable = new CPSvrNew7221SKospiTable("CPSvrNew7221SKospi");
            AddTable(curTable);
            curTable = new CPSvrNew7221SFutureTable("CPSvrNew7221SFuture");
            AddTable(curTable);
            curTable = new CPSvrNew7221SOptionTable("CPSvrNew7221SOption");
            AddTable(curTable);
            curTable = new CmeCurrTable("CmeCurr");
            AddTable(curTable);
            curTable = new CmeMstTable("CmeMst");
            AddTable(curTable);
            curTable = new CPConclusionTable("CPConclusion");
            AddTable(curTable);
            curTable = new StockChartTable("StockChart");
            AddTable(curTable);
            curTable = new EasyTrader.DataSet.CmeDailyTable("CmeDaily");
            AddTable(curTable);
            curTable = new EasyTrader.DataSet.DowIndustryTable("DowIndustry");
            AddTable(curTable);
            curTable = new EasyTrader.DataSet.SNP500Table("SNP500");
            AddTable(curTable);
            curTable = new EasyTrader.DataSet.NASDAQTable("NASDAQ");
            AddTable(curTable);
            curTable = new EasyTrader.DataSet.EnglandFTSETable("EnglandFTSE");
            AddTable(curTable);
            curTable = new EasyTrader.DataSet.DeuchDAXTable("DeuchDAX");
            AddTable(curTable);
            curTable = new EasyTrader.DataSet.FranceCACTable("FranceCAC");
            AddTable(curTable);
            curTable = new EasyTrader.DataSet.FutOptDailyTable("FutOptDaily");
            AddTable(curTable);
            curTable = new EasyTrader.DataSet.FutureDailyAmpTable("FutureDailyAmp");
            AddTable(curTable);
            curTable = new EasyTrader.DataSet.FXKRWTable("FXKRW");
            AddTable(curTable);
        }

        public EasyTrader.DataSet.ETDataTable GetWorldCurTable(string a_WorldCode)
        {
            EasyTrader.DataSet.ETDataTable curTable = null;
            if (a_WorldCode == ".DJI")
            {
                curTable = (EasyTrader.DataSet.ETDataTable)this.Tables["DowIndustry"];
            }
            else if (a_WorldCode == "SPX")
            {
                curTable = (EasyTrader.DataSet.ETDataTable)this.Tables["SNP500"];
            }
            else if (a_WorldCode == "COMP")
            {
                curTable = (EasyTrader.DataSet.ETDataTable)this.Tables["NASDAQ"];
            }
            else if (a_WorldCode == "GB#FTSE")
            {
                curTable = (EasyTrader.DataSet.ETDataTable)this.Tables["EnglandFTSE"];
            }
            else if (a_WorldCode == "GR#DAX")
            {
                curTable = (EasyTrader.DataSet.ETDataTable)this.Tables["DeuchDAX"];
            }
            else if (a_WorldCode == "FR#CAC")
            {
                curTable = (EasyTrader.DataSet.ETDataTable)this.Tables["FranceCAC"];
            }

            return curTable;
        }

        public EasyTrader.DataSet.CmeDailyTable GetCmeDailyTable()
        {
            return (EasyTrader.DataSet.CmeDailyTable)this.Tables["CmeDaily"];
        }

        public EasyTrader.DataSet.FXKRWTable GetFXKRWTable()
        {
            return (EasyTrader.DataSet.FXKRWTable)this.Tables["FXKRW"];
        }

        public EasyTrader.DataSet.FutureDailyAmpTable GetFutureDailyAmpTable()
        {
            return (EasyTrader.DataSet.FutureDailyAmpTable)this.Tables["FutureDailyAmp"];
        }

        public StockChartTable GetStockChartTable()
        {
            return (StockChartTable)this.Tables["StockChart"];
        }

        public FutureMstTable GetFutureMstTable()
        {
            return (FutureMstTable)this.Tables["FutureMst"];
        }

        public EasyTrader.DataSet.FutOptChartTable GetFutOptChartTable()
        {
            return (EasyTrader.DataSet.FutOptChartTable)this.Tables["FutOptChart"];
        }

        public EasyTrader.DataSet.FutOptDailyTable GetFutOptDailyTable()
        {
            return (EasyTrader.DataSet.FutOptDailyTable)this.Tables["FutOptDaily"];
        }

        public FutureCurOnlyTable GetFutureCurOnlyTable()
        {
            return (FutureCurOnlyTable)this.Tables["FutureCurOnly"];
        }

        public FutureJpBidTable GetFutureJpBidTable()
        {
            return (FutureJpBidTable)this.Tables["FutureJpBid"];
        }

        public CPSvrNew7221SKospiTable GetCPSvrNew7221SKospiTable()
        {
            return (CPSvrNew7221SKospiTable)this.Tables["CPSvrNew7221SKospi"];
        }

        public CPSvrNew7221Table GetCPSvrNew7221Table()
        {
            return (CPSvrNew7221Table)this.Tables["CPSvrNew7221"];
        }

        public CPSvrNew7221SFutureTable GetCPSvrNew7221SFutureTable()
        {
            return (CPSvrNew7221SFutureTable)this.Tables["CPSvrNew7221SFuture"];
        }

        public CPSvrNew7221SOptionTable GetCPSvrNew7221SOptionTable()
        {
            return (CPSvrNew7221SOptionTable)this.Tables["CPSvrNew7221SOption"];
        }

        public CPSvr8111STable GetCPSvr8111STable()
        {
            return (CPSvr8111STable)this.Tables["CPSvr8111S"];
        }

        public CmeCurrTable GetCmeCurrTable()
        {
            return (CmeCurrTable)this.Tables["CmeCurr"];
        }

        public CmeMstTable GetCmeMstTable()
        {
            return (CmeMstTable)this.Tables["CmeMst"];
        }

        public CPConclusionTable GetCPConclusionTable()
        {
            return (CPConclusionTable)this.Tables["CPConclusion"];
        }

        public void AddTable(DataTable a_DataTable)
        {
            this.Tables.Add(a_DataTable);
        }
        public DataTable GetTable(string a_TableName)
        {
            return this.Tables[a_TableName];
        }

        public void Clear(string a_TableName)
        {
            this.Tables[a_TableName].Clear();
        }

        private int m_ServerSec = 0;
        public int ServerSec
        {
            get { return m_ServerSec; }
            set { m_ServerSec = value; }
        }
    }
}
